import NativeClient from "../../A-FRAME/native/NativeClient";
import { NCAPIURI, NCBody, NCPoint, NCPointData, NCResponse, NCResult } from "./api.config.client";
import GlobalData from "../../game/GlobalData";
import { AudioManager } from "../../AudioManager";

type URIRequest = { [uri in NCAPIURI]: {} extends NCResult<uri> ? never : uri }[NCAPIURI];
type URISend = { [uri in NCAPIURI]: {} extends NCResult<uri> ? uri : never }[NCAPIURI]

export class ClientAPI {
	private static async request<uri extends URIRequest>(api: uri, data?: NCBody<uri>, ccdata?: any) {
		let struct = NativeClient.sendMessage(api, data, true, ccdata);
		return struct.response as NCResponse<uri>;
	}

	private static send<uri extends URISend>(api: uri, data?: NCBody<uri>) {
		NativeClient.sendMessage(api, data, false, null);
	}

	/** 获取游戏类型：A纯游戏、B完整商业化 */
	public static async GameType() {
		let response = await ClientAPI.request(NCAPIURI.GameType);
		return response.data.type;
	}

	/** 获取设备ID */
	public static async DeviceID() {
		let response = await ClientAPI.request(NCAPIURI.DeviceID);
		return response.data;
	}

	/** 本地化接口 */
	public static async Local() {
		let response = await ClientAPI.request(NCAPIURI.LOCAL);
		return response.data;
	}

	/** 广告请求 */
	public static async AD(type: NCBody<NCAPIURI.AD>['type'], floatType: NCBody<NCAPIURI.AD>['floatType']) {
		ClientAPI.Float(floatType);
		AudioManager.ins.mute = true;
		let response = await ClientAPI.request(NCAPIURI.AD, { type, floatType }, mtec.string.random(5, 36));
		AudioManager.ins.mute = false;
		return response.data.status == 'ad-over';
	}

	public static levelResult(
		level: NCBody<NCAPIURI.levelResult>['level'],
		result: NCBody<NCAPIURI.levelResult>['result']
	) {
		ClientAPI.send(NCAPIURI.levelResult, { level, result });
	}

	/**
	 * 在浏览器中打开一个指定的链接
	 * @param url
	 * @returns
	 */
	public static Link(url: NCBody<NCAPIURI.LINK>['url']) {
		ClientAPI.send(NCAPIURI.LINK, { url });
	}

	/** 设置剪切板 */
	public static SetClipboard(text: NCBody<NCAPIURI.SetClipboard>['text']) {
		ClientAPI.send(NCAPIURI.SetClipboard, { text });
	}

	public static Float(type: NCBody<NCAPIURI.Float>['type']) {
		ClientAPI.send(NCAPIURI.Float, { type });
	}

	/** 评分弹窗 */
	public static ScorePop() {
		ClientAPI.send(NCAPIURI.ScorePop);
	}

	public static CloseLoading() {
		ClientAPI.send(NCAPIURI.CloseLoading);
	}

	/**
	 * 埋点上包
	 * @param point 点位标识符
	 * @param data 点位数据
	 */
	public static Point<P extends NCPoint>(point: P, data: Partial<NCPointData<P>>) {
		let list: string[] = [];

		Reflect.ownKeys(data).forEach(key => {
			let v = Reflect.get(data, key);
			let t = typeof v;
			if (!['number', 'string', 'boolean', 'bigint'].includes(t)) {
				return void 0;
			}

			if (t == 'bigint') {
				t = 'number';
			}

			list.push(String(key) + '@' + ({ string: 'S', number: 'N', boolean: 'B' })[t] + ':' + String(v));
		});

		ClientAPI.send(NCAPIURI.Point, { point, value: list.length > 0 ? list.join(';') : '' });
	}
}
